/**
 * 支付管理控制器 - 处理支付订单的创建、查询和管理
 *
 * 开发人员：徐少洋
 * 开发时间：2025-10-25 至 2025-10-28
 * 模块职责：提供支付订单相关的REST API接口，支持订单创建、查询、状态管理等功能
 *
 * 技术要点：
 * - RESTful API设计，遵循REST规范
 * - 多租户架构，企业级数据隔离
 * - AOP审计日志记录操作轨迹
 * - 参数验证和异常处理机制
 * - ZPAY支付集成和回调处理
 *
 * 开发故事：负责支付系统的核心控制器开发，与前端支付页面深度配合，确保支付流程的完整性和安全性。
 */
package com.pbl.controller;

import com.pbl.aspect.AuditLog;
import com.pbl.common.enums.PaymentStatus;
import com.pbl.common.model.ApiResponse;
import com.pbl.dto.payment.CreateOrderRequest;
import com.pbl.dto.payment.MarkSuccessRequest;
import com.pbl.entity.PaymentOrder;
import com.pbl.repository.PaymentOrderRepository;
import com.pbl.service.PaymentService;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/enterprises/{enterpriseId}/payments")
public class PaymentController {

    private final PaymentService paymentService;
    private final PaymentOrderRepository paymentOrderRepository;

    public PaymentController(PaymentService paymentService, PaymentOrderRepository paymentOrderRepository) {
        this.paymentService = paymentService;
        this.paymentOrderRepository = paymentOrderRepository;
    }

    @GetMapping("/orders")
    public ApiResponse<List<PaymentOrder>> list(@PathVariable Long enterpriseId,
                                                @RequestParam(required = false) PaymentStatus status) {
        List<PaymentOrder> list = status == null
                ? paymentOrderRepository.findByEnterprise_IdOrderByCreatedAtDesc(enterpriseId)
                : paymentOrderRepository.findByEnterprise_IdAndStatusOrderByCreatedAtDesc(enterpriseId, status);
        return ApiResponse.success(list);
    }

    @AuditLog(action = "payment.createOrder", resource = "payment")
    @PostMapping("/orders")
    public ApiResponse<PaymentOrder> createOrder(@PathVariable Long enterpriseId,
                                                 @Valid @RequestBody CreateOrderRequest req) {
        if (req.getProductId() != null) {
            return ApiResponse.success(paymentService.createOrderWithProduct(enterpriseId, req.getUserId(), req.getProductId(), req.getName(), req.getAmount(), req.getPayType()));
        } else {
            return ApiResponse.success(paymentService.createOrder(enterpriseId, req.getUserId(), req.getName(), req.getAmount(), req.getPayType()));
        }
    }

    @GetMapping("/orders/{outTradeNo}")
    public ApiResponse<PaymentOrder> getOrder(@PathVariable Long enterpriseId, @PathVariable String outTradeNo) {
        return ApiResponse.success(paymentService.getByOutTradeNo(outTradeNo));
    }

    @AuditLog(action = "payment.markSuccess", resource = "payment")
    @PostMapping("/orders/{outTradeNo}/success")
    public ApiResponse<PaymentOrder> markSuccess(@PathVariable Long enterpriseId, @PathVariable String outTradeNo,
                                                 @Valid @RequestBody MarkSuccessRequest req) {
        return ApiResponse.success(paymentService.markSuccess(outTradeNo, req.getTradeNo()));
    }

    @AuditLog(action = "payment.closeOrder", resource = "payment")
    @PostMapping("/orders/{outTradeNo}/close")
    public ApiResponse<PaymentOrder> closeOrder(@PathVariable Long enterpriseId, @PathVariable String outTradeNo) {
        return ApiResponse.success(paymentService.closeOrder(outTradeNo));
    }

    @GetMapping("/orders/{outTradeNo}/simulate-payurl")
    public ApiResponse<Map<String, String>> simulatePayUrl(@PathVariable Long enterpriseId,
                                                           @PathVariable String outTradeNo,
                                                           @RequestParam(defaultValue = "wxpay") String type,
                                                           @RequestParam String name,
                                                           @RequestParam String money,
                                                           @RequestParam(required = false) String notifyUrl,
                                                           @RequestParam(required = false) String returnUrl) {
        return ApiResponse.success(paymentService.buildZpayParams(outTradeNo, type, name, money, notifyUrl, returnUrl));
    }
}
